#include <iostream>
#include <vector>
#include <bitset>
#include <type_traits>
using namespace std;

// template <class T>
// constexpr T pi = T(3.1415926535897932385L); // 变量模板

// template <class T>
// T circular_area(T r) // 函数模板
// {
//     return pi<T> * r * r; // pi<T> 是变量模板实例化
// }

// template <std::size_t N>
// constexpr std::size_t factorial = N * factorial<N - 1>;

// // 特化
// template <>
// constexpr std::size_t factorial<0> = 1;

// template <class T>
// constexpr bool is_const_v = std::is_const<T>::value;

// int main()
// {
//     // 使用不同精度的π
//     std::cout.precision(6);
//     std::cout << "float π: " << pi<float> << std::endl;
//     std::cout.precision(10);
//     std::cout << "double π: " << pi<double> << std::endl;

//     std::cout.precision(6);
//     float radius1 = 2.5;
//     std::cout << "半径为 " << radius1 << " 的圆面积: " << circular_area(radius1)
//               << std::endl;
//     std::cout.precision(10);

//     double radius2 = 2.5;
//     std::cout << "半径为 " << radius2 << " 的圆面积: " << circular_area(radius2)
//               << std::endl;
//     std::cout << factorial<5> << std::endl;
//     std::cout << factorial<10> << std::endl;

//     return 0;
// }

// int main() {
//	// 另一个泛型Lambda示例 - 返回两个参数中较大的一个
//	auto getMax = [](const auto& a, const auto& b) {
//		return a > b ? a : b;
//	};
//
//	std::cout << "最大整数: " << getMax(10, 20) << std::endl;
//	std::cout << "最大字符串: " << getMax(std::string("apple"),std::string("banana")) << std::endl;
//
//	// 这里参数写成auto&&时类似引用折叠部分讲的万能引用
//	// 实参是左值就是左值引用，实参是右值就是右值引用
//	auto func = [](auto&& x, auto& y) {
//		x += 97;
//		y += 97;
//	};
//
//	// func(1, 2);
//	int x1 = 0, x2 = 1;
//	func(x1, x2);
//	func(std::move(x1), x2);
//
//	//std::string s1("hello worldxxxxxxxxxxxx");
//	//func(move(s1), x2);
//	//func(s1, x2);
//
//	// 也可以写成这样带可变模板参数的写法
//	std::vector<std::string> v;
//	auto f1 = [&v](auto&&... ts)
//	{
//		v.emplace_back(std::forward<decltype(ts)>(ts)...);
//	};
//
//	std::string s1("xxxxxx");
//	f1(s1);
//	f1(move(s1));
//	f1("yyyyy");
//	f1(10, 'x');
//	f1(s1.begin(), s1.end());
//
//	return 0;
// }
//
// int main()
//{
//	std::vector<int> numbers = { 1, 2, 3, 4, 5 };
//	// 使用表达式初始化捕获的变量
//	auto p = std::make_unique<int>(10);
//
//	auto lambda1 = [value = 5, ptr = std::move(p), &numbers]() {
//		std::cout << "捕获的值: " << value << std::endl;
//		std::cout << "捕获的智能指针值: " << *ptr << std::endl;
//		std::cout << "捕获的vector大小: " << numbers.size() << std::endl;
//	};
//
//	lambda1();
//
//	// 另一个例子 - 在捕获时计算值
//	int x = 10;
//	auto lambda2 = [y = x * 2]() {
//		std::cout << "y = x * 2 = " << y << std::endl;
//	};
//
//	lambda2();
//
//	// 以下带模板参数的写法是C++20才开始支持的
//	// 泛型 lambda，operator() 是一个拥有两个（模板）形参的模板
//	auto glambda = []<class T>(T a, auto && b) { return a < b; };
//
//	// 泛型 lambda，operator() 是一个拥有一个形参包的模板
//	std::vector<std::string> v;
//	auto f2 = [&v]<typename... Args>(Args&&... ts)
//	{
//		v.emplace_back(std::forward<Args>(ts)...);
//	};
//
//	std::string s1("hello wrold");
//	f2(s1);
//	f2("1111111");
//	f2(10, 'y');
//	for (auto& e : v)
//	{
//		std::cout << e << " ";
//	}
//	std::cout << std::endl;
//
//	return 0;
// }

// C++14 普通函数可以直接用auto做返回类型，自动推导返回类型
// int x = 1;
// auto f1() { return x; } // 返回类型是 int
// auto& f2() { return x; } // 返回类型是 int&
// auto f3(int x) { return x * 1.5; } // 返回类型是double
//
//// 报错，多返回语句需类型一致
////auto f4(int x) {
////	if (x > 0)
////		return 1.0; // double
////	else
////		return 2; // int → 错误：类型不一致
////}
//
// template<class T>
// auto f4(T x) {
//	if constexpr (is_integral_v<T>)
//		return 1; // double
//	else
//		return 1.1; // int → 错误：类型不一致
//}
//
// int main()
//{
//	cout << f4(1) << endl;
//	cout << f4(1.1) << endl;
//
//	return 0;
//}

// int x = 1;
// int& y = x;
// decltype(auto) f1() { return x; } // 返回类型是 int，同 decltype(x)
// decltype(auto) f2() { return (x); } // 返回类型是 int&，同 decltype((x))
// decltype(auto) f3() { return y; } // 返回类型是 int&，同 decltype(y)

// template<typename F, typename... Args>
// decltype(auto) call(F&& f, Args&&... args)
// {
// 	return std::forward<F>(f)(std::forward<Args>(args)...);
// }

// int main()
// {
// 	int b = 0b101010;
// 	cout << typeid(b).name() << endl;

// 	std::bitset<16> foo;
// 	std::bitset<16> bar(0xfa2);
// 	//std::bitset<16> baz(std::string("0101111001"));
// 	std::bitset<16> baz(0b0101111001);

// 	std::cout << "foo: " << foo << '\n';
// 	std::cout << "bar: " << bar << '\n';
// 	std::cout << "baz: " << baz << '\n';

//     return 0;
// }

// int main() {
// 	// 使用数字分隔符提高大数字的可读性
// 	int million = 10'0000'0000;
// 	long hexValue = 0xDEAD'BEEF;
// 	double pi = 3.141'592'653'59;
// 	unsigned long long bigBinary = 0b1010'1011'1011'1010;
// 	std::cout << "一百万: " << million << std::endl;
// 	std::cout << "十六进制值: 0x" << std::hex << hexValue << std::dec <<
// 		std::endl;
// 	std::cout << "π: " << pi << std::endl;
// 	std::cout << "二进制值: " << std::bitset<16>(bigBinary) << std::endl;

// 	// 实际应用示例 - 定义常量
// 	const int MAX_USERS = 1'000'000;
// 	const double EARTH_RADIUS_KM = 6'371.0;

// 	const long long BIG_NUMBER = 1234'5678'9123;
// 	std::cout << "最大用户数: " << MAX_USERS << std::endl;
// 	std::cout << "地球半径(km): " << EARTH_RADIUS_KM << std::endl;
// 	std::cout << "大数字: " << BIG_NUMBER << std::endl;

// 	return 0;
// }

// // 聚合类
// struct Employee {
// 	std::string name = "Unknown";
// 	int id = -1;
// 	double salary = 0.0;

// 	// Employee(int id) {}
// 	// Employee() = default;
// };

// int main()
// {
// 	Employee e1 = {"xxx", 1, 1.1};

// 	// C++14
// 	Employee e2 = { "John" }; // name="John", id=-1, salary=0.0
// 	Employee e3 = { "Alice", 123 }; // name="Alice", id=123, salary=0.0
// 	Employee e4 = {}; // 值初始化，等同于e1

// 	// C++20中初始化聚合类的方式，解决C++14必须按顺序给值初始化的问题
// 	Employee e5 = { .id = 1, .salary{1.1} }; // name="Alice", id= 1, salary=1.1

// 	// C++20中还支持嵌套类的初始化
// 	struct Inner {
// 		int a;
// 		int b;
// 	};
// 	struct Outer {
// 		Inner i;
// 		int c;
// 	};

// 	Outer o1{ .i{1, 2}, .c = 3 };
// 	// 或
// 	Outer o2{ .i = {.a = 1, .b = 2}, .c = 3 };

// 	return 0;
// }

// #include <iterator>
// #include <utility>
// #include <vector>

// class stream
// {
// public:
// 	using flags_type = int;
// public:
// 	flags_type flags() const { return flags_; }

// 	/// 以 newf 替换 flags_ 并返回旧值。
// 	flags_type flags(flags_type newf) { return std::exchange(flags_, newf); }

// private:
// 	flags_type flags_ = 0;
// };

// template< class T, class U >
// void exchange1(T& obj, U&& new_value)
// {}

// int main()
// {
// 	stream s;
// 	std::cout << s.flags() << '\n';
// 	std::cout << s.flags(12) << '\n';
// 	std::cout << s.flags() << "\n\n";

// 	std::vector<int> v = { 10,20,30 };
// 	// 因为第二模板形参有默认值，故能以花括号初始化式列表为第二实参。
// 	// 下方表达式等价于 std::exchange(v, std::vector<int>{1, 2, 3, 4});
// 	// exchange1(v, { 1, 2, 3, 4 });

// 	std::vector<int> ret = std::exchange(v, { 1, 2, 3, 4 });
// 	for (auto e : v)
// 		std::cout << e << " ";
// 	std::cout << "\n";

// 	for (auto e : ret)
// 		std::cout << e << " ";
// 	std::cout << "\n";

// 	std::cout << "\n\n斐波那契数列: ";
// 	for (int a{ 0 }, b{ 1 }; a < 100; a = std::exchange(b, a + b))
// 		std::cout << a << ", ";

// 	std::cout << "...\n";

// 	return 0;
// }

// // C++98就有的字⾯量后缀
// // 整形和浮点数的字⾯量后缀
// auto a = 10; // int
// auto b = 10u; // unsigned int
// auto c = 10l; // long
// auto d = 10ul; // unsigned long
// auto e = 10ll; // long long
// auto f = 10ull; // unsigned long long
// auto g = 3.14; // double
// auto h = 3.14f; // float
// auto i = 3.14l; // long double

// #include <string>
// #include <string_view>

// std::string operator"" _s(const char *str, size_t len)
// {
//     return std::string(str, len);
// }

// std::string_view operator"" _sv(const char *str, size_t len)
// {
//     return std::string_view(str, len);
// }

// float operator""_e(const char *str)
// {
//     return std::stof(std::string(str));
// }

// constexpr long double operator"" _km(unsigned long long int x)
// {
//     return x * 1000.0; // 将公里转换为米
// }

// constexpr long double operator"" _pi(long double x)
// {
//     return x * 3.14159265358979323846L;
// }

// int main()
// {
//     auto s1 = "hello"_s;
//     auto s2 = "Hello\0World"_s;
//     auto sv1 = "hello"_sv;
//     auto distance = 5_km; // 相当于 auto distance = 5000.0L;
//     auto angle = 2.0_pi;  // 相当于 auto angle = 6.28318530717958647692L;
//     auto x = 12.3_e;

//     return 0;
// }

// #include <iostream>
// #include <string>
// #include <chrono>
// #include <thread>

// // 使用标准的字面量
// using namespace std::literals;

// int main()
// {
//     // 字符串字面量
//     auto str = "Hello"s; // 类型是 std::string，不是 const char*

//     std::cout << str.size() << std::endl;
//     std::this_thread::sleep_for(std::chrono::milliseconds(500));

//     // 时间字面量
//     std::this_thread::sleep_for(500ms);

//     return 0;
// }

// std::make_unique的使用演示，该代码来源于官方文档
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <memory>
#include <utility>

struct Vec3
{
	int x, y, z;
	Vec3(int x = 0, int y = 0, int z = 0) noexcept : x(x), y(y), z(z) {}

	friend std::ostream& operator<<(std::ostream& os, const Vec3& v)
	{
		return os << "{ x=" << v.x << ", y=" << v.y << ", z=" << v.z << " }";
	}
};

// 向输出迭代器输出斐波那契数列。
template<typename OutputIt>
OutputIt fibonacci(OutputIt first, OutputIt last)
{
	for (int a = 0, b = 1; first != last; ++first)
	{
		*first = b;
		b += std::exchange(a, b);
	}
	return first;
}

//int main()
//{
//	// 创建单个对象（会调用构造函数）
//	auto ptr1 = std::make_unique<int>(); // 初始化为0
//	auto ptr2 = std::make_unique<int>(42); // 初始化为42
//	// 创建数组（元素会被值初始化）
//	auto arr = std::make_unique<int[]>(5); // 5个int，都初始化为0
//
//	unique_ptr<int> up1(new int);
//	unique_ptr<int[]> up2(new int[5]);
//
//	// 使用默认构造函数。
//	std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
//	// 使用匹配这些参数的构造函数。
//	std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
//	// 创建指向 5 个元素数组的 unique_ptr。
//	std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);
//
//	std::cout << "make_unique<Vec3>(): " << *v1 << '\n'
//		<< "make_unique<Vec3>(0,1,2): " << *v2 << '\n'
//		<< "make_unique<Vec3[]>(5): ";
//
//	for (std::size_t i = 0; i < 5; ++i)
//		std::cout << std::setw(i ? 30 : 0) << v3[i] << '\n';
//	std::cout << '\n';
//
//	// make_unique_for_overwrite是C++20支持的，相比make_unique而言，他的特点是不初始化
//	// 创建指向未初始化的 10 个整数的数组的 unique_ptr，然后以斐波那契数列予以填充。
//	std::unique_ptr<int[]> i1 = std::make_unique_for_overwrite<int[]>(10);
//	fibonacci(i1.get(), i1.get() + 10);
//
//	std::cout << "make_unique_for_overwrite<int[]>(10), fibonacci(...): [" <<
//		i1[0];
//	for (std::size_t i = 1; i < 10; ++i)
//		std::cout << ", " << i1[i];
//	std::cout << "]\n";
//
//	return 0;
//}

// #include <cstddef>
// #include <iostream>
// #include <tuple>
// #include <utility>
// #include <array>

// template <typename T, T... ints>
// void print_sequence(int id, std::integer_sequence<T, ints...> int_seq)
// {
// 	std::cout << id << ") 大小为 " << int_seq.size() << " 的序列: ";
// 	((std::cout << ints << ' '), ...);
// 	std::cout << '\n';
// }

// //int main()
// //{
// //	print_sequence(1, std::integer_sequence<unsigned, 9, 2, 5, 1, 9, 1, 6>{});
// //	print_sequence(2, std::make_integer_sequence<int, 12>{}); // [0,12)
// //	print_sequence(3, std::make_index_sequence<10>{});
// //
// //	print_sequence(4, std::index_sequence_for<std::ios, float, int, signed>{});
// //
// //	return 0;
// //}

// //template<typename Array, std::size_t... I>
// //void print_array_impl(const Array& arr, std::index_sequence<I...>) {
// //	((std::cout << arr[I] << ' '), ...);
// //}
// //
// //template<typename T, std::size_t N>
// //void print_array(const std::array<T, N>& arr) {
// //	print_array_impl(arr, std::make_index_sequence<N>{});
// //}

// //int main()
// //{
// //	// 打印array
// //	std::array<int, 4> arr{ 1, 2, 3, 4 };
// //	print_array(arr); // 输出: 1 2 3 4
// //
// //	// 打印元组
// //	auto t = std::make_tuple(10, 3.14, "Hello", 'A');
// //	std::cout << "元组内容: ";
// //	print_tuple(t);
// //
// //	return 0;
// //}

//#include <iostream>
//#include <sstream>
//#include <iomanip>
//#include <string>
//int main() {
//	// 输出带引号的字符串
//	std::string text = "Hello, World!";
//	std::cout << "Without quoted: " << text << std::endl;
//
//	std::cout << "With quoted: " << std::quoted(text) << std::endl;
//	// 输出:
//	// Without quoted: Hello, World!
//	// With quoted: "Hello, World!"
//	// 输入带引号的字符串
//
//	std::string str = "\"Hello, World!\"";
//	std::istringstream input("\"Hello, World!\"");
//	input >> std::quoted(text);
//	//input
//	std::cout << "Extracted: " << text << std::endl;
//	// 输出: Extracted: Hello, World!
//}

//#include <iostream>
//#include <iomanip>
//#include <string>
//#include <sstream>
////
//int main() {
//	// 使用单引号作为分隔符
//	std::string text = "It's a test";
//	std::cout << "Default: " << std::quoted(text) << std::endl;
//	std::cout << "Single quotes: " << std::quoted(text, '%') << std::endl;
//	std::cout << "Single quotes: " << std::quoted(text, '\'') << std::endl;
//
//
//	// 处理包含分隔符的字符串
//	//std::string complex = R"(He said "Hello" and left)";
//	std::string complex = "(He said \"Hello\" and left)";
//
//	std::cout << "Complex string: " << std::quoted(complex) << std::endl;
//
//	// 使用字符串流测试输入输出
//	std::stringstream ss1;
//	ss1 << std::quoted(complex);
//
//	std::string extracted;
//	ss1 >> std::quoted(extracted);
//	std::cout << "Extracted: " << extracted << std::endl;
//
//	// 包含转义字符的字符串
//	std::stringstream ss2;
//	text = "Line1\nLine2\tTabbed";
//	ss2 << std::quoted(text);
//
//	std::cout << "Original: " << text << std::endl;
//	std::cout << "Quoted: " << ss2.str() << std::endl;
//
//	ss2 >> std::quoted(extracted);
//	std::cout << "Extracted: " << extracted << std::endl;
//}